package com.uduemc.biso.node.web.api.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.file.FileReader;
import cn.hutool.core.util.StrUtil;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.pagehelper.PageInfo;
import com.uduemc.biso.core.extities.center.AgentNodeServerDomain;
import com.uduemc.biso.core.extities.center.Host;
import com.uduemc.biso.core.extities.center.SysServer;
import com.uduemc.biso.core.extities.node.custom.LoginNode;
import com.uduemc.biso.core.extities.pojo.ICP35;
import com.uduemc.biso.core.utils.*;
import com.uduemc.biso.node.core.common.entities.SSL;
import com.uduemc.biso.node.core.common.feign.CSSLFeign;
import com.uduemc.biso.node.core.entities.HDomain;
import com.uduemc.biso.node.core.entities.HRepertory;
import com.uduemc.biso.node.core.entities.HSSL;
import com.uduemc.biso.node.core.feign.HDomainFeign;
import com.uduemc.biso.node.core.feign.HSSLFeign;
import com.uduemc.biso.node.core.node.extities.DomainRedirectList;
import com.uduemc.biso.node.core.property.GlobalProperties;
import com.uduemc.biso.node.core.utils.RestResultUtil;
import com.uduemc.biso.node.core.utils.SitePathUtil;
import com.uduemc.biso.node.web.api.component.RequestHolder;
import com.uduemc.biso.node.web.api.service.*;
import com.uduemc.biso.node.web.component.NginxServer;
import com.uduemc.biso.node.web.utils.ResubmitUtil;
import feign.form.util.CharsetUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.net.IDN;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Service
public class DomainServiceImpl implements DomainService {

    private final Logger logger = LoggerFactory.getLogger(getClass());

    @Resource
    private HDomainFeign hDomainFeign;

    @Resource
    private RequestHolder requestHolder;

    @Resource
    private ObjectMapper objectMapper;

    @Resource
    private ServerService serverServiceImpl;

    @Resource
    private CenterService centerServiceImpl;

    @Resource
    private GlobalProperties globalProperties;

    @Resource
    private RedisUtil redisUtil;

    @Resource
    private NginxServer nginxServer;

    @Resource
    private AsyncDomainService asyncDomainServiceImpl;

    @Resource
    private NginxService nginxServiceImpl;

    @Resource
    private RepertoryService repertoryServiceImpl;

    @Resource
    private HostService hostServiceImpl;

    @Resource
    private CSSLFeign cSSLFeign;

    @Resource
    private HSSLFeign hSSLFeign;

    @Resource
    private LoginService loginServiceImpl;

    @Resource
    private HttpServletRequest request;

    /**
     * 同步阻塞通过 feign 获取默认的域名，如果不存在则创建默认的域名
     *
     * @return
     * @throws IOException
     * @throws JsonProcessingException
     * @throws JsonMappingException
     * @throws JsonParseException
     */
//	private HDomain getDefaultDomainByFeign() throws  IOException {
//		Host host = requestHolder.getHost();
//		return getDefaultDomainByFeign(host);
//	}
    private HDomain getDefaultDomainByFeign(Long hostId) throws IOException {
        Host host = hostServiceImpl.getInfoById(hostId);
        if (host == null) {
            return null;
        }
        return getDefaultDomainByFeign(host);
    }

    synchronized private HDomain getDefaultDomainByFeign(Host host) throws IOException {
        RestResult restResult = hDomainFeign.findDefaultDomainByHostId(host.getId());
        HDomain hDomain = ResultUtil.data(restResult, HDomain.class);
        if (hDomain == null) {
            hDomain = new HDomain();
            SysServer sysServer = serverServiceImpl.getServerByHost(host);
            if (sysServer == null) {
                logger.error("sysServer is empty!");
                return null;
            }
            String domainName = host.getRandomCode() + "." + sysServer.getDomain();
            hDomain.setAccessType((short) 0).setDomainName(domainName).setDomainType((short) 0).setHostId(host.getId()).setRedirect(0L).setRemark("")
                    .setStatus((short) 1);
            // 写入
            restResult = hDomainFeign.insert(hDomain);
            if (restResult != null) {
                return ResultUtil.data(restResult, HDomain.class);
            }
        }

        return hDomain;
    }

    @Override
    public HDomain getDefaultDomain() throws IOException {
        Long hostId = requestHolder.getHost().getId();
        return getDefaultDomain(hostId);
    }

    @Override
    public HDomain getDefaultDomain(long hostId) throws IOException {

        String KEY = globalProperties.getNodeRedisKey().getDefalutHDomainHostKey(hostId);
        HDomain hDomain = (HDomain) redisUtil.get(KEY);
        if (hDomain == null) {
            // 阻塞获取数据并且存入缓存中
            hDomain = getDefaultDomainByFeign(hostId);
            logger.info("getDefaultDomainByFeign() HDomain: " + hDomain);
            redisUtil.set(KEY, hDomain, 3600 * 2);
        }

        // 判断是否是代理商登录用户，如果是代理商登录用户则默认域名需要改变
        if (loginServiceImpl.isAgent()) {
            Short domainType = hDomain.getDomainType();
            if (domainType != null && domainType.shortValue() == (short) 0) {
                // 系统默认域名
                Host host = requestHolder.getHost();
                LoginNode loginNode = requestHolder.getCurrentLoginNode();
                AgentNodeServerDomain agentNodeServerDomain = loginNode.getLoginNodeAgent().getAgentNodeServerDomain();
                if (agentNodeServerDomain != null) {
                    String agentNodeDefaultDomain = AgentLinkUtil.agentNodeDefaultDomain(host, agentNodeServerDomain);
                    hDomain.setDomainName(agentNodeDefaultDomain);
                }
            }
        }

        return hDomain;
    }

    @Override
    public List<HDomain> bindIndos() throws IOException {
        Long hostId = requestHolder.getHost().getId();
        return bindIndos(hostId);
    }

    @Override
    public List<HDomain> bindIndos(long hostId) throws IOException {
        RestResult restResult = hDomainFeign.findUserDomainByHostId(hostId);
        @SuppressWarnings("unchecked")
        List<HDomain> list = (ArrayList<HDomain>) ResultUtil.data(restResult, new TypeReference<ArrayList<HDomain>>() {
        });
        return list;
    }

    @Override
    public List<HDomain> allDomain() throws IOException {
        RestResult restResult = hDomainFeign.findAllByHostId(requestHolder.getHost().getId());
        @SuppressWarnings("unchecked")
        List<HDomain> data = (List<HDomain>) RestResultUtil.data(restResult, new TypeReference<List<HDomain>>() {
        });
        // 判断是否是代理商登录用户，如果是代理商登录用户则默认域名需要改变
        if (loginServiceImpl.isAgent()) {
            if (CollUtil.isNotEmpty(data)) {
                data.forEach(hDomain -> {
                    Short domainType = hDomain.getDomainType();
                    if (domainType != null && domainType.shortValue() == (short) 0) {
                        // 系统默认域名
                        Host host = requestHolder.getHost();
                        LoginNode loginNode = requestHolder.getCurrentLoginNode();
                        AgentNodeServerDomain agentNodeServerDomain = loginNode.getLoginNodeAgent().getAgentNodeServerDomain();
                        if (agentNodeServerDomain != null) {
                            String agentNodeDefaultDomain = AgentLinkUtil.agentNodeDefaultDomain(host, agentNodeServerDomain);
                            hDomain.setDomainName(agentNodeDefaultDomain);
                        }
                    }
                });
            }
        }
        return data;
    }

    @Override
    public boolean isExistDomainName(String domainName) throws IOException {
        List<SysServer> sysServerList = centerServiceImpl.getAllSysServer();
        for (SysServer sysServer : sysServerList) {
            if (sysServer.getDomain().equals(domainName)) {
                return true;
            }
        }

        RestResult restResult = hDomainFeign.findByDomainName(domainName);
        HDomain data = RestResultUtil.data(restResult, HDomain.class);
        if (data == null) {
            return false;
        }
        return true;
    }

    @Override
    public boolean bindCurrentDomain(String domainName) throws IOException {
        if (isExistDomainName(domainName)) {
            return false;
        }

        String asciiDomain = DomainUtil.toASCII(domainName);
        if (StrUtil.isBlank(asciiDomain)) {
            return false;
        }

        HDomain domain = new HDomain();
        domain.setHostId(requestHolder.getHost().getId()).setRedirect(0L).setDomainType((short) 1).setAccessType((short) 1).setDomainName(domainName)
                .setStatus((short) 0).setRemark("");

        SysServer sysServer = serverServiceImpl.selfSysServer();
        // 如果是香港、美国等不需要备案的服务器，直接放行
        if (sysServer.getIicp() != null && sysServer.getIicp().intValue() == 0) {
            domain.setStatus((short) 1);
            domain.setRemark("");
        } else {
            ICP35 icp35 = centerServiceImpl.getIcpDomain(domainName);
            if (icp35 != null && icp35.getResult() != -1) {
                String remark = objectMapper.writeValueAsString(icp35);
                if (icp35.getResult() == 1) {
                    domain.setStatus((short) 1);
                    domain.setRemark(remark);
                } else if (icp35.getResult() == 0) {
                    domain.setStatus((short) 2);
                    domain.setRemark("");
                }
            }
        }

        RestResult restResult = hDomainFeign.insert(domain);
        HDomain data = RestResultUtil.data(restResult, HDomain.class);
        if (data == null || !data.getDomainName().equals(domainName)) {
            return false;
        }

        // 检测绑定如果不存在的域名数据存在绑定的 nginx ，则进行删除
        cleanInvalidHDomainnNginxServer(domain.getHostId());
        return nginxServiceImpl.bindDomain(requestHolder.getHost(), data);
    }

    @Override
    public JsonResult bindSSL(long hostId, long domainId, long resourcePrivatekeyId, long resourceCertificateId, short httpsOnly)
            throws IOException {
        HDomain hDomain = infoByIdHostId(domainId, hostId);
        if (hDomain == null || hDomain.getAccessType().shortValue() == (short) 0) {
            return JsonResult.messageError("绑定证书的域名非用户域名");
        }
        HRepertory privatekey = repertoryServiceImpl.getInfoByid(resourcePrivatekeyId);
        HRepertory certificate = repertoryServiceImpl.getInfoByid(resourceCertificateId);
        if (privatekey == null || certificate == null) {
            return JsonResult.illegal();
        }
        if (!privatekey.getSuffix().toLowerCase().equals("key")) {
            return JsonResult.messageError("绑定证书的私钥文件需要 key 结尾");
        }
        if (!(certificate.getSuffix().toLowerCase().equals("crt") || certificate.getSuffix().toLowerCase().equals("pem"))) {
            return JsonResult.messageError("绑定的证书文件需要 crt或pem 结尾");
        }

        String basePath = globalProperties.getSite().getBasePath();
        Host host = hostServiceImpl.getInfoById(hostId);
        String privatekeypath = SitePathUtil.getUserNginxSSLPathByCode(basePath, host.getRandomCode()) + "/" + privatekey.getOriginalFilename();
        String certificatepath = SitePathUtil.getUserNginxSSLPathByCode(basePath, host.getRandomCode()) + "/" + certificate.getOriginalFilename();
        // 验证
        File privateKeyFile = new File(privatekeypath);
        File certFile = new File(certificatepath);
        String validateResult = OpensslUtil.validate(certFile, privateKeyFile);
        if (StrUtil.isNotBlank(validateResult)) {
            // 证书与私钥不匹配
            return JsonResult.messageError("证书与私钥不匹配");
        }

        if (httpsOnly < 0 || httpsOnly > 1) {
            return JsonResult.illegal();
        }

        // 写入数据库
        RestResult restResult = cSSLFeign.save(hostId, domainId, resourcePrivatekeyId, resourceCertificateId, httpsOnly);
        SSL ssl = RestResultUtil.data(restResult, SSL.class);
        if (ssl == null) {
            return JsonResult.assistance();
        }

        // 重启 nginx 配置
        boolean bindDomain = nginxServiceImpl.bindDomain(host, hDomain);
        if (!bindDomain) {
            return JsonResult.assistance();
        }

        // 检测绑定如果不存在的域名数据存在绑定的 nginx ，则进行删除
        cleanInvalidHDomainnNginxServer(hostId);

        ssl.setStatus(makeSSLStatuc(ssl));

        JsonResult result = JsonResult.messageSuccess("绑定证书成功", ssl);
        redisUtil.set(ResubmitUtil.redisKey(request), result, 10L);
        return result;
    }

    @Override
    public JsonResult updateHttpsOnly(long domainId, short httpsOnly) throws IOException {
        if (httpsOnly < 0 || httpsOnly > 1) {
            return JsonResult.illegal();
        }
        SSL infoSSL = infoSSL(domainId);
        if (infoSSL == null || infoSSL.getHssl() == null) {
            return JsonResult.messageError("未能获取到绑定ssl的域名证书信息");
        }

        RestResult restResult = hSSLFeign.updateHttpsOnly(infoSSL.getHssl().getId(), httpsOnly);
        HSSL data = ResultUtil.data(restResult, HSSL.class);
        if (data == null) {
            return JsonResult.assistance();
        }
        return JsonResult.messageSuccess("操作成功", infoSSL(domainId));
    }

    @Override
    public JsonResult bindSSL(long domainId, long resourcePrivatekeyId, long resourceCertificateId, short httpsOnly)
            throws IOException {
        Long hostId = requestHolder.getHost().getId();
        return bindSSL(hostId, domainId, resourcePrivatekeyId, resourceCertificateId, httpsOnly);
    }

    @Override
    public HDomain getCurrentInfoById(long id) throws IOException {
        Long hostId = requestHolder.getHost().getId();
        return infoByIdHostId(id, hostId);
    }

    @Override
    public HDomain infoByIdHostId(long id, long hostId) throws IOException {
        RestResult restResult = hDomainFeign.findDomainByHostidAndId(id, hostId);
        HDomain data = RestResultUtil.data(restResult, HDomain.class);
        return data;
    }

    @Override
    public boolean deleteItem(HDomain hDomain) throws IOException {
        nginxServer.unbindDomain(requestHolder.getHost(), hDomain.getDomainName());
        RestResult restResult = hDomainFeign.deleteById(hDomain.getId());
        boolean bool = restResult != null;
        if (bool) {
            // 是否存在绑定的ssl，如果存在则直接删除绑定ssl数据信息
            cSSLFeign.deletes(hDomain.getHostId(), hDomain.getId());
        }
        return bool;
    }

    @Override
    public DomainRedirectList getCurrentRedirectLIst() throws IOException {
        RestResult restResult = hDomainFeign.findDomainRedirectByHostId(requestHolder.getHost().getId());
        DomainRedirectList data = RestResultUtil.data(restResult, DomainRedirectList.class);
        return data;
    }

    @Override
    public boolean updateItem(HDomain update) throws IOException {
        RestResult restResult = hDomainFeign.updateAllById(update);
        HDomain data = RestResultUtil.data(restResult, HDomain.class);
        return data != null && data.getId().longValue() == update.getId().longValue();
    }

    @Override
    public HDomain getInfoByDomainName(String domainName) throws IOException {
        RestResult restResult = hDomainFeign.findByDomainName(domainName);
        HDomain hDomain = RestResultUtil.data(restResult, HDomain.class);
        return hDomain;
    }

    @Override
    public PageInfo<HDomain> findPageInfo(String domainName, long hostId, short domainType, short status, int orderBy, int page, int pageSize)
            throws IOException {
        RestResult restResult = hDomainFeign.findPageInfo(domainName, hostId, domainType, status, orderBy, page, pageSize);
        @SuppressWarnings("unchecked")
        PageInfo<HDomain> data = (PageInfo<HDomain>) RestResultUtil.data(restResult, new TypeReference<PageInfo<HDomain>>() {
        });
        return data;
    }

    @Override
    public List<HDomain> findByWhere(long minId, short domainType, short status, int orderBy, int page, int pageSize)
            throws IOException {
        RestResult restResult = hDomainFeign.findByWhere(minId, domainType, status, orderBy, page, pageSize);
        @SuppressWarnings("unchecked")
        List<HDomain> data = (List<HDomain>) RestResultUtil.data(restResult, new TypeReference<List<HDomain>>() {
        });
        return data;
    }

    @Override
    public List<HDomain> findByWhere(long minId, short status, int pageSize)
            throws IOException {
        return findByWhere(minId, (short) 1, status, 1, 0, pageSize);
    }

    @Override
    public List<HDomain> findByHostIdDomainTypeStatus(long hostId, short domainType, short status, int orderBy)
            throws IOException {
        RestResult restResult = hDomainFeign.findByHostIdDomainTypeStatus(hostId, domainType, status, orderBy);
        @SuppressWarnings("unchecked")
        List<HDomain> data = (List<HDomain>) RestResultUtil.data(restResult, new TypeReference<List<HDomain>>() {
        });
        return data;
    }

    @Override
    public List<HDomain> findByHostIdDomainTypeStatus(long hostId) throws IOException {
        return findByHostIdDomainTypeStatus(hostId, (short) 1, (short) -1, 1);
    }

    @Override
    public void resetIcp(HDomain hDomain) {
        if (hDomain == null || StrUtil.isBlank(hDomain.getDomainName())) {
            return;
        }
        Short domainType = hDomain.getDomainType();
        if (domainType.shortValue() == (short) 0) {
            return;
        }

        String domain = hDomain.getDomainName();
        String KEY = globalProperties.getSiteRedisKey().getIcpDomainCachekey(domain);
        redisUtil.del(KEY);
        asyncDomainServiceImpl.asyncIcpDomain(hDomain);
    }

    @Override
    public void resetIcp(List<HDomain> listHDomain) {
        if (CollectionUtils.isEmpty(listHDomain)) {
            return;
        }
        for (HDomain hDomain : listHDomain) {
            resetIcp(hDomain);
        }
    }

    @Override
    public Map<String, Object> icpInfos(HDomain hDomain) {
        if (hDomain == null || StrUtil.isBlank(hDomain.getDomainName())) {
            return null;
        }
        Short domainType = hDomain.getDomainType();
        if (domainType.shortValue() == (short) 0) {
            return null;
        }

        String domain = hDomain.getDomainName();
        String remark = hDomain.getRemark();
        ICP35 icp35 = null;
        if (StrUtil.isNotBlank(remark)) {
            try {
                icp35 = objectMapper.readValue(remark, ICP35.class);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        Map<String, Object> result = new HashMap<>();
        result.put("domain", domain);
        result.put("data", icp35);
        String KEY = globalProperties.getSiteRedisKey().getIcpDomainCachekey(domain);
        icp35 = (ICP35) redisUtil.get(KEY);
        result.put("cache", icp35);

        return result;
    }

    @Override
    public List<Map<String, Object>> icpInfos(List<HDomain> listHDomain) {
        if (CollectionUtils.isEmpty(listHDomain)) {
            return null;
        }
        List<Map<String, Object>> result = new ArrayList<>();
        for (HDomain hDomain : listHDomain) {
            Map<String, Object> icpInfos = icpInfos(hDomain);
            if (icpInfos != null) {
                result.add(icpInfos);
            }
        }
        return result;
    }

    @Override
    public String ngxinServerContent(HDomain hDomain) {
        String asciiDomain = DomainUtil.toASCII(hDomain.getDomainName());
        if (StrUtil.isBlank(asciiDomain)) {
            return hDomain.getDomainName() + " 非有效域名。";
        }
        return ngxinServerContent(hDomain.getHostId(), asciiDomain);
    }

    @Override
    public String ngxinServerContent(long hostId, String domainName) {
        String makeIncludeFile = nginxServer.makeIncludeFile(hostId, domainName);
        if (!FileUtil.isFile(makeIncludeFile)) {
            return "";
        }
        String readString = FileUtil.readString(makeIncludeFile, CharsetUtil.UTF_8);
        return readString;
    }

    @Override
    public Date nginxServerFileLastModified(HDomain hDomain) {
        return nginxServerFileLastModified(hDomain.getHostId(), hDomain.getDomainName());
    }

    @Override
    public Date nginxServerFileLastModified(long hostId, String domainName) {
        String makeIncludeFile = nginxServer.makeIncludeFile(hostId, domainName);
        if (!FileUtil.isFile(makeIncludeFile)) {
            return null;
        }
        return FileUtil.lastModifiedTime(makeIncludeFile);
    }

    @Override
    public SSL infoSSL(HDomain hDomain) throws IOException {
        return infoSSL(hDomain.getHostId(), hDomain.getId());
    }

    @Override
    public SSL infoSSL(long hostId, long domainId) throws IOException {
        RestResult restResult = cSSLFeign.infoByHostDomainId(hostId, domainId);
        SSL data = RestResultUtil.data(restResult, SSL.class);
        if (data == null) {
            return null;
        }
        data.setStatus(makeSSLStatuc(data));
        return data;
    }

    @Override
    public SSL infoSSL(long domainId) throws IOException {
        Long hostId = requestHolder.getHost().getId();
        return infoSSL(hostId, domainId);
    }

    @Override
    public List<SSL> infosSSL() throws IOException {
        Long hostId = requestHolder.getHost().getId();
        return infosSSL(hostId);
    }

    @Override
    public List<SSL> infosSSL(long hostId) throws IOException {
        RestResult restResult = cSSLFeign.infos(hostId);
        @SuppressWarnings("unchecked")
        List<SSL> data = (List<SSL>) RestResultUtil.data(restResult, new TypeReference<List<SSL>>() {
        });
        if (CollUtil.isNotEmpty(data)) {
            for (SSL ssl : data) {
                ssl.setStatus(makeSSLStatuc(ssl));
            }
        }
        return data;
    }

    @Override
    public SSL deleteSSL(long sslId) throws IOException {
        RestResult restResult = cSSLFeign.infoBySSLId(sslId);
        SSL data = RestResultUtil.data(restResult, SSL.class);
        if (data == null) {
            return null;
        }
        data.setStatus(makeSSLStatuc(data));

        restResult = cSSLFeign.delete(sslId);
        Integer row = RestResultUtil.data(restResult, Integer.class);
        if (row == null || row.intValue() != 1) {
            throw new RuntimeException("删除SSL数据失败。sslId: " + sslId);
        }
        HDomain domain = data.getDomain();
        Long hostId = domain.getHostId();
        Host host = hostServiceImpl.getInfoById(hostId);
        if (host == null) {
            throw new RuntimeException("数据异常，通过 hostId 未能获取到 host 数据。sslId: " + sslId);
        }
        // 重启 nginx 配置
        boolean bindDomain = nginxServiceImpl.bindDomain(host, domain);
        if (!bindDomain) {
            throw new RuntimeException("删除SSL后，重新配置nginx.server失败！");
        }

        // 检测绑定如果不存在的域名数据存在绑定的 nginx ，则进行删除
        cleanInvalidHDomainnNginxServer(hostId);

        return data;
    }

    @Override
    public void cleanInvalidHDomainnNginxServer(long hostId) throws IOException {
        List<HDomain> bindIndos = bindIndos(hostId);
        String makeIncludePath = nginxServer.makeIncludePath(hostId);
        if (!FileUtil.isDirectory(makeIncludePath)) {
            return;
        }
        File[] ls = FileUtil.ls(makeIncludePath);
        for (File file : ls) {
            String name = file.getName();
            boolean bool = true;
            for (HDomain hDomain : bindIndos) {
                String configFileName = nginxServer.makeIncludeFileName(IDN.toASCII(hDomain.getDomainName()));
                if (name.equals(configFileName)) {
                    bool = false;
                    break;
                }
            }
            if (bool) {
                FileUtil.del(file);
            }
        }

        // access.*.nginxlog 日志文件删除

        // error.*.nginxlog 日志文件删除
    }

    @Override
    public void cleanInvalidHDomainnNginxServer() throws IOException {
        Long hostId = requestHolder.getHost().getId();
        cleanInvalidHDomainnNginxServer(hostId);
    }

    @Override
    public short makeSSLStatuc(SSL ssl) throws IOException {
        if (ssl == null) {
            return -1;
        }
        HDomain domain = ssl.getDomain();
        if (domain == null) {
            return -1;
        }
        Long hostId = domain.getHostId();

        HRepertory privatekey = ssl.getPrivatekey();
        HRepertory certificate = ssl.getCertificate();
        if (privatekey == null || certificate == null) {
            return -1;
        }

        String basePath = globalProperties.getSite().getBasePath();
        Host host = hostServiceImpl.getInfoById(hostId);
        String privatekeypath = SitePathUtil.getUserNginxSSLPathByCode(basePath, host.getRandomCode()) + "/" + privatekey.getOriginalFilename();
        String certificatepath = SitePathUtil.getUserNginxSSLPathByCode(basePath, host.getRandomCode()) + "/" + certificate.getOriginalFilename();
        // 验证
        File privateKeyFile = new File(privatekeypath);
        File certFile = new File(certificatepath);
        String validateResult = OpensslUtil.validate(certFile, privateKeyFile);
        if (StrUtil.isNotBlank(validateResult)) {
            // 证书与私钥不匹配
            return 2;
        }

        String nginxServerConf = nginxServer.makeIncludeFile(hostId, domain.getDomainName());
        File file = new File(nginxServerConf);
        if (!file.isFile()) {
            return 3;
        }
        String readString = FileReader.create(new File(nginxServerConf)).readString();

        Pattern patter = Pattern.compile(".*listen\\s+443\\s+ssl.*", Pattern.DOTALL);
        Matcher matcher = patter.matcher(readString);
        if (!matcher.matches()) {
            return 3;
        }

        patter = Pattern.compile(".*ssl_certificate\\s+.*/" + certificate.getOriginalFilename() + ".*", Pattern.DOTALL);
        matcher = patter.matcher(readString);
        if (!matcher.matches()) {
            return 3;
        }

        patter = Pattern.compile(".*ssl_certificate_key\\s+.*/" + privatekey.getOriginalFilename() + ".*", Pattern.DOTALL);
        matcher = patter.matcher(readString);
        if (!matcher.matches()) {
            return 3;
        }
        return 1;
    }

    @Override
    public List<HSSL> infosSSLByRepertoryId(long repertoryId) throws IOException {
        Long hostId = requestHolder.getHost().getId();
        return infosSSLByRepertoryId(hostId, repertoryId);
    }

    @Override
    public List<HSSL> infosSSLByRepertoryId(long hostId, long repertoryId)
            throws IOException {
        RestResult restResult = hSSLFeign.infosByRepertoryId(hostId, repertoryId);
        @SuppressWarnings("unchecked")
        List<HSSL> listHSSL = (ArrayList<HSSL>) ResultUtil.data(restResult, new TypeReference<ArrayList<HSSL>>() {
        });
        return listHSSL;
    }

}
